/*=========================================================================
 *
 *  Copyright Arash Akbarinia
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/

/**
* @file SlicesFromVolume.cxx
*
*/

#include <itkImage.h>
#include <itkImageFileReader.h>
#include <itkImageFileWriter.h>
#include <itkRescaleIntensityImageFilter.h>
#include <itkExtractImageFilter.h>
#include <itkImageSeriesWriter.h>
#include <itkNumericSeriesFileNames.h>

// TODO: convert printing to logging

int main ( int argc, char** argv )
{
  // Verify the number of parameters in the command line
  if ( argc < 3 )
    {
      std::cerr << "Usage: " << std::endl;
      std::cerr << argv[0]
                << " InputVolume OutputFolder FileFormat(default=slice\%03d.png)"
                << std::endl;
      return EXIT_FAILURE;
    }

  const unsigned int InputDimension = 3;
  typedef signed short InternalPixelType;
  typedef itk::Image< InternalPixelType, InputDimension > InputVolumeType;

  const unsigned int OutputDimension = 2;
  typedef unsigned short OutputPixelType;
  typedef itk::Image< OutputPixelType, OutputDimension > OutputImageType;
  typedef itk::Image< OutputPixelType, InputDimension > OutputVolumeType;

  typedef itk::ImageFileReader< InputVolumeType > ReaderType;
  typedef itk::ImageSeriesWriter< OutputVolumeType, OutputImageType > WriterType;
  typedef itk::RescaleIntensityImageFilter< InputVolumeType, OutputVolumeType > CastingFilterType;
  typedef itk::NumericSeriesFileNames NameGeneratorType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writer = WriterType::New();
  CastingFilterType::Pointer caster = CastingFilterType::New();
  NameGeneratorType::Pointer NameGenerator = NameGeneratorType::New();

  reader->SetFileName ( argv[1] );
  caster->SetInput ( reader->GetOutput() );

  std::string SeriesFormat = argv[2];
  std::string FileFormat;
  if ( argc > 3 )
    {
      FileFormat = argv[3];
    }
  else
    {
      FileFormat = "slice\%03d.png";
    }
  SeriesFormat = SeriesFormat + "/" + FileFormat;
  NameGenerator->SetSeriesFormat ( SeriesFormat );
  NameGenerator->SetStartIndex ( 0 );
  NameGenerator->SetIncrementIndex ( 1 );

  try
    {
      caster->Update();

      NameGenerator->SetEndIndex ( ( unsigned int ) caster->GetOutput()->GetLargestPossibleRegion().GetSize() [2] - 1 );
      std::vector< std::string > names = NameGenerator->GetFileNames();

      writer->SetInput ( caster->GetOutput() );
      writer->SetFileNames ( names );
      writer->Update();
    }
  catch ( itk::ExceptionObject & excep )
    {
      std::cerr << "Exception caught !" << std::endl;
      std::cerr << excep << std::endl;
    }

  return EXIT_SUCCESS;
}
